
const port = 5555;
const app = require('./app');
const http = require('http');

const server = http.createServer(app.callback())
const websocket = require("ws");

//--socket--
const wss = new websocket.Server({ server });
//在线用户
const onlineUsers = {};
//当前在线人数
let onlineCount = 0;



//大屏在线人数
const gbOnLineUsersMap = new Map(
  // [
  //   ['001',{entId: "d8f5ad41bdeb449a87875ccd4d0a86bd",personId: "c7d89267da11474ab4af38252bc9ae7b"}],
  //   ['002',{entId: "d8f5ad41bdeb449a87875ccd4d0a86bd",personId: "222222222222222"}],
  // ]
);
app.context.gbOnLineUsersMap = gbOnLineUsersMap;




//绑定事件，建立连接
wss.on("connection", (socket) => {
  console.log("websocket已连接");

  socket.isAlive = true;
  socket.on('pong', function() {
    this.isAlive = true
  })


  socket.on("message", (message) => {
    //打印收到的消息
    const messageObj = JSON.parse(message);
    // console.log('收到发来的消息', messageObj);
    //监听后台下载列表变化发的消息
    if (messageObj.type == "downNum") {
      console.log("收到后台发的消息：", messageObj);
      if (messageObj.uid && onlineUsers.hasOwnProperty(messageObj.uid)) {
        console.log(
          "hasOwnProperty(uid）",
          onlineUsers.hasOwnProperty(messageObj.uid)
        );
        const sendContent = JSON.stringify({
          uid: messageObj.uid,
          personId: messageObj.personId,
          entId: messageObj.entId,
          type: messageObj.type,
          downNum: messageObj.message,
        });
        console.log("准备发给前端的消息：", sendContent);
        onlineUsers[messageObj.uid].send(sendContent);
      }
    }
    //监听新用户加入
    if (messageObj.type === "login") {
      const obj = messageObj;
      //将新加入用户的唯一标识当作socket的名称，后面退出的时候会用到
      socket.personId = obj.personId;
      socket.entId = obj.entId;
      socket.userid = obj.userid;
      //检查在线列表，如果不在里面就加入
      if (!onlineUsers.hasOwnProperty(obj.userid)) {
        onlineUsers[obj.userid] = socket;
        //在线人数+1
        onlineCount++;
      }
      // 获取对象所有的键
      const keys = Object.keys(onlineUsers);
      console.log("==在线人数==明细", keys.length, keys);
    }
  
     //监听用户退出
     if (messageObj.type === "disconnect") {
      console.log(
        "==用户申请退出==",
        onlineUsers.hasOwnProperty(socket.userid),
        socket.userid
      );
      //将退出的用户从在线列表中删除
      if (onlineUsers.hasOwnProperty(socket.userid)) {
        //退出用户的信息
        var obj = { userid: socket.userid };
        //删除
        delete onlineUsers[obj.userid];
        //在线人数-1
        onlineCount--;
      }
      // 获取对象所有的键
      const keys = Object.keys(onlineUsers);
      console.log("==在线人数==明细", keys.length, keys);
    }


    //---------------------------数据大屏bigScreenWarn---------------------------------------------
    //进入大屏
    if (messageObj.type === 'insertBigScreenWarn') {
      console.log('--insertBigScreenWarn--messageObj--:',messageObj);
      const { personId, entId,timeMap } = messageObj;
      const combineKey = entId + '_' + personId + '_' + timeMap;
      gbOnLineUsersMap.set(combineKey,{entId,personId,socket,timeMap})
    }

    //离开大屏
    if (messageObj.type === 'outBigScreenWarn') {
      const { personId, entId, timeMap} = messageObj;
      const combineKey = entId + '_' + personId+ '_' + timeMap;
      if (gbOnLineUsersMap.has(combineKey)) {
        const {socket:existSocket } = gbOnLineUsersMap.get(combineKey);
        existSocket.terminate();
        gbOnLineUsersMap.delete(combineKey)
      } else {
        console.error('--outBigScreenWarn时，未找到当前socket--')
      }
    }

    //获取数据
    if(messageObj.type === 'getBigScreenWData') {
      const { baseUserId, entId,message:msgStr ,uid } = messageObj;
      console.log('--getBigScreenWData--messageObj--:',messageObj)
      if (gbOnLineUsersMap.has(uid)) {
        const finalMsgObj = {
          type:'getBigScreenWData',
          entId,
          personId:baseUserId,
          uid,
          ...(msgStr ? JSON.parse(msgStr) : {})
        }
        const {socket:currSocket } = gbOnLineUsersMap.get(uid);
        const sendContent = JSON.stringify(finalMsgObj);
        currSocket.send(sendContent);
      }else {
        console.error('--getBigScreenWData时，未找到当前socket--')
      }
    }


  });



  socket.on("close", () => {
    console.log("当前websocket连接已关闭");
  });


});


//心跳机制
//每隔30s给所有客户端发送一个ping
const hearBeatInterval = setInterval(function ping() {
  wss.clients.forEach(function each(socket) {
    if (socket.isAlive === false) return socket.terminate();
    socket.isAlive = false;
    socket.ping(); 
  });
}, 30000);


wss.on('close', function close() {
  console.log('ws服务关闭')
  clearInterval(hearBeatInterval);
});


server.listen(port);
server.on('error', onError);
server.on('listening', onListening);


function onError(error) {
  if (error.syscall !== 'listen') {
    throw error;
  }

  const bind = typeof port === 'string'
    ? 'Pipe ' + port
    : 'Port ' + port;

  // handle specific listen errors with friendly messages
  switch (error.code) {
  case 'EACCES':
    console.error(bind + ' requires elevated privileges');
    process.exit(1);
    break;
  case 'EADDRINUSE':
    console.error(bind + ' is already in use');
    process.exit(1);
    break;
  default:
    throw error;
  }
}


function onListening() {

  const addr = server.address();
  const bind = typeof addr === 'string'
    ? 'pipe ' + addr
    : 'port ' + addr.port;
    console.log(`--socket project listening on ${bind}--`)
}



